/**
 * 画布状态管理 - stores/canvas.ts
 * 使用Pinia进行状态管理，这是Vue3推荐的状态管理库
 * 这个文件管理整个画布的状态，包括组件列表、画布配置等
 */

import { defineStore } from 'pinia'  // 导入Pinia的defineStore函数
import type { Component } from '@/types'  // 导入组件类型定义

/**
 * 画布状态接口定义
 * 定义了画布store中所有状态的类型
 */
export interface CanvasState {
  components: Component[]           // 组件列表
  activeComponentId: string | null  // 当前激活的组件ID
  canvasConfig: {                   // 画布配置
    width: number                   // 画布宽度
    height: number                  // 画布高度
    backgroundColor: string         // 背景颜色
    backgroundImage: string         // 背景图片
  }
  scale: number                     // 画布缩放比例
}

/**
 * 定义画布状态管理store
 * 'canvas'是这个store的唯一标识符
 */
export const useCanvasStore = defineStore('canvas', {
  /**
   * state: 状态定义
   * 这里定义了画布需要管理的所有数据
   */
  state: (): CanvasState => ({
    // 组件列表：存储画布上所有的组件
    components: [],
    
    // 当前激活的组件ID：用户当前选中的组件
    // null表示没有选中任何组件
    activeComponentId: null,
    
    // 画布配置：画布的基本设置
    canvasConfig: {
      width: 1920,                    // 画布宽度（像素）
      height: 1080,                   // 画布高度（像素）
      backgroundColor: '#0c1426',     // 画布背景颜色（深蓝色）
      backgroundImage: ''             // 画布背景图片（空字符串表示无背景图）
    },
    
    // 画布缩放比例：用于缩放显示，1表示100%
    scale: 1
  }),

  /**
   * getters: 计算属性
   * 基于state计算出的衍生数据，会自动缓存
   */
  getters: {
    /**
     * 获取当前激活的组件
     * 根据activeComponentId从组件列表中找到对应的组件
     */
    activeComponent: (state) => {
      return state.components.find(comp => comp.id === state.activeComponentId)
    },
    
    /**
     * 获取组件总数
     * 返回画布上组件的数量
     */
    componentCount: (state) => state.components.length
  },

  /**
   * actions: 操作方法
   * 定义了修改state的所有方法
   */
  actions: {
    /**
     * 添加组件到画布
     * @param component 要添加的组件对象
     */
    addComponent(component: Component) {
      this.components.push(component)        // 将组件添加到列表末尾
      this.activeComponentId = component.id  // 设置新添加的组件为激活状态
    },

    /**
     * 从画布删除组件
     * @param id 要删除的组件ID
     */
    removeComponent(id: string) {
      // 找到要删除的组件在数组中的位置
      const index = this.components.findIndex(comp => comp.id === id)
      if (index > -1) {
        // 从数组中移除该组件
        this.components.splice(index, 1)
        // 如果删除的是当前激活的组件，则清空激活状态
        if (this.activeComponentId === id) {
          this.activeComponentId = null
        }
      }
    },

    /**
     * 更新组件信息
     * @param id 要更新的组件ID
     * @param updates 要更新的属性（部分更新）
     */
    updateComponent(id: string, updates: Partial<Component>) {
      // 找到要更新的组件
      const component = this.components.find(comp => comp.id === id)
      if (component) {
        // 使用Object.assign合并更新的属性
        Object.assign(component, updates)
      }
    },

    /**
     * 设置激活的组件
     * @param id 组件ID，null表示取消选中
     */
    setActiveComponent(id: string | null) {
      this.activeComponentId = id
    },

    /**
     * 更新画布配置
     * @param config 要更新的配置项（部分更新）
     */
    updateCanvasConfig(config: Partial<CanvasState['canvasConfig']>) {
      // 合并新的配置到现有配置中
      Object.assign(this.canvasConfig, config)
    },

    /**
     * 设置画布缩放比例
     * @param scale 缩放比例（1为100%，0.5为50%，2为200%）
     */
    setScale(scale: number) {
      this.scale = scale
    },

    /**
     * 清空画布
     * 删除所有组件并取消选中状态
     */
    clearCanvas() {
      this.components = []              // 清空组件列表
      this.activeComponentId = null     // 取消激活状态
    },

    /**
     * 复制组件
     * 创建一个现有组件的副本，并稍微偏移位置
     * @param id 要复制的组件ID
     */
    copyComponent(id: string) {
      // 找到要复制的组件
      const component = this.components.find(comp => comp.id === id)
      if (component) {
        // 创建新组件，复制所有属性
        const newComponent = {
          ...component,                           // 复制所有属性
          id: `comp_${Date.now()}`,              // 生成新的唯一ID
          style: {
            ...component.style,                  // 复制样式
            left: component.style.left + 20,    // X坐标向右偏移20像素
            top: component.style.top + 20       // Y坐标向下偏移20像素
          }
        }
        // 添加新组件到画布
        this.addComponent(newComponent)
      }
    }
  }
})